<?php
/**
 * Created by PhpStorm.
 * User: admin
 * Date: 2019/3/21
 * Time: 20:54
 */

namespace App\Http\Controllers\Api\V1;


use App\Http\Controllers\Api\ApiController;
use App\Library\Common;
use App\Library\Time;
use App\Messages\ShippingStatus10Shipper;
use App\Messages\ShippingStatus20Shipper;
use App\Messages\ShippingStatus30Receiver;
use App\Messages\ShippingStatus35Receiver;
use App\Messages\ShippingStatus45Finance;
use App\Models\CarSite;
use App\Models\Driver;
use App\Models\DriverBank;
use App\Models\Member;
use App\Models\MemberRelation;
use App\Models\Order;
use App\Models\OwnerRoutes;
use App\Models\Shipping;
use App\Models\ShippingPay;
use App\Services\CarService;
use App\Services\MemberService;
use App\Services\NotificationService;
use App\Services\RouteService;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Http\Request;
use Validator;

class ShippingController extends ApiController
{
    /**
     * 运货列表展示
     * @see https://run.mockplus.cn/DQQd1cZtfuI7ebzw/index.html?to=0D36676B-86E3-437A-8FF7-1CC5BB42D4D0
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function shippingList(Request $request)
    {
        try {

            $validator = Validator::make($request->all(), [
                'driver_uuid' => 'required|size:36',
                'status' => 'required',
                'page' => 'required|integer',
                'limit' => 'required|integer'
            ]);

            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            $fields = [
                'o.sender_uuid',
                'o.receiver_uuid',
                'o.price',
                'o.order_no',
                'o.price_unit',
                'o.cargo_type',
                'o.route_id',
                'o.end_time',
                'v_shipping.shipping_no',
                'v_shipping.status',
                'v_shipping.global_status',
                'v_shipping.created_at AS start_time', // 接单时间
                'v_shipping.shipment_end_time AS load_time', // 装货时间
                'v_shipping.deliver_end_time AS unload_time', // 卸货时间
                'v_shipping_pay.created_at AS payment_time', // 结算时间
                'v_shipping_pay.status AS payment_status', // 结算状态，必须为10
                'v_shipping.updated_at AS end_time', // 结单时间
                'v_shipping.status AS end_status', // 结单时间，结单状态，必须为40
                'v_owner_routes.driving_distance', // 驾车距离
                'v_owner_routes.line_distance', // 直线距离
            ];

            $res = Shipping::select($fields)
                ->leftJoin('v_orders AS o', 'o.id', '=', 'v_shipping.order_id')
                ->leftJoin('v_shipping_pay', 'v_shipping_pay.shipping_id', '=', 'v_shipping.id')
                ->leftJoin('v_owner_routes', 'v_owner_routes.id', '=', 'o.route_id')
                ->where('v_shipping.driver_uuid', $request->get('driver_uuid'))
                ->whereIn('v_shipping.status', explode(',', $request->get('status')))
                ->orderBy('v_shipping.id', 'desc')
                ->paginate($request->get('limit', self::DEFAULT_PAGE_LIMIT))
                ->toArray();
            if (empty($res['data'])) {
                return $this->success();
            }

            $memberFields = ['name', 'phone', 'avatar'];

            $oRoute = new OwnerRoutes();
            foreach ($res['data'] as $key => $value) {
                $routeInfo = RouteService::getInstance()->getDetailedAddressByRouteId($value['route_id'], $oRoute);

                // 各种流程时间转换，null=>''
                $res['data'][$key]['global_status'] = $value['global_status'] ?? 0;
                $res['data'][$key]['load_time'] = $value['load_time'] ?? '';
                $res['data'][$key]['unload_time'] = $value['unload_time'] ?? '';
                $res['data'][$key]['payment_time'] = isset($value['payment_status']) ? ($value['payment_status'] == 10 ? $value['payment_time'] : '') : '';
                $res['data'][$key]['end_time'] = isset($value['end_status']) ? ($value['end_status'] == 40 ? $value['end_time'] : '') : '';
                unset($res['data'][$key]['payment_status'], $res['data'][$key]['end_status']);

                // 获取收发货地址
                $res['data'][$key]['src_detail'] = $routeInfo['srcDetail'] ?? '';
                $res['data'][$key]['dst_detail'] = $routeInfo['dstDetail'] ?? '';

                // 运货状态名称
                $res['data'][$key]['status_name'] = Shipping::setStatusNamesForShippingList($value['status']);
                unset($res['data'][$key]['status']);

                // 装货/交货/接单/结束日期 设定
                $res['data'][$key]['time_name'] = Shipping::setTimeNamesForShippingList($value['status']);

                // 获取用户相关信息
                $oSender = Member::select($memberFields)->where('uuid', $value['sender_uuid'])->first();
                $oReceiver = Member::select($memberFields)->where('uuid', $value['receiver_uuid'])->first();
                $res['data'][$key]['sender_name'] = $oSender->name ?? '';
                $res['data'][$key]['sender_phone'] = $oSender->phone ?? '';
                $res['data'][$key]['sender_avatar'] = $oSender->avatar ?? '';
                $res['data'][$key]['receiver_name'] = $oReceiver->name ?? '';
                $res['data'][$key]['receiver_phone'] = $oReceiver->phone ?? '';
                $res['data'][$key]['receiver_avatar'] = $oReceiver->avatar ?? '';
            }

            return $this->table($res['data'], $res['total']);

        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 运单详情页
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function shippingDetail(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'shipping_no' => 'required'
            ]);

            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            $fields = [
                // 地址和人物
                'v_orders.sender_uuid',
                'v_orders.receiver_uuid',
                'v_orders.route_id',

                // 货物信息
                'v_orders.cargo_type',
                'v_orders.price',
                'v_orders.price_unit',
//                'v_orders.todo', // 可载货物
//                'v_orders.todo', // 燃油补贴
                'v_orders.total_car_num',
                'v_orders.shipping_car_num',
                'v_orders.order_remark',

                // 订单
                'v_orders.order_no',
                'v_shipping.created_at AS start_time', // 接单时间
                'v_shipping.shipment_end_time AS load_time', // 装货时间
                'v_shipping.deliver_end_time AS unload_time', // 卸货时间
                'v_shipping_pay.created_at AS payment_time', // 结算时间
                'v_shipping_pay.status AS payment_status', // 结算状态，必须为10
                'v_shipping.updated_at AS end_time', // 结单时间
                'v_shipping.status AS end_status', // 结单时间，结单状态，必须为40
                'v_shipping.load_num',
                'v_shipping.load_pic',
                'v_shipping.unload_num',
                'v_shipping.unload_pic',
                'v_shipping.shipping_no',
                'v_shipping.pay_status',
                'v_shipping.global_status',

                'v_shipping_pay.load_amount AS pay_load_amount',
                'v_shipping_pay.loss_amount AS pay_loss_amount',
                'v_shipping_pay.actual_amount AS pay_actual_amount',
                'v_shipping_pay.status AS pay_status', // 支付状态，0待支付，10已支付
                'v_shipping_pay.created_at AS pay_created_at',
                'v_shipping_pay.updated_at AS pay_updated_at',
            ];

            $oShipping = Shipping::select($fields)
                ->leftJoin('v_orders', 'v_orders.id', '=', 'v_shipping.order_id')
                ->leftJoin('v_shipping_pay', 'v_shipping_pay.shipping_id', '=', 'v_shipping.id')
                ->where('v_shipping.shipping_no', $request->get('shipping_no'))
                ->first();
            if (is_null($oShipping)) {
                throw new \Exception('没有数据');
            }

            $routeInfo = RouteService::getInstance()->getDetailedAddressByRouteId($oShipping->route_id, new OwnerRoutes());

            // 获取用户相关信息
            $memberFields = ['name', 'phone', 'avatar'];
            $oSender = Member::select($memberFields)->where('uuid', $oShipping->sender_uuid)->first();
            $oReceiver = Member::select($memberFields)->where('uuid', $oShipping->receiver_uuid)->first();

            $builder = [];
            $builder['route_info']['sender_name'] = $oSender->name ?? '';
            $builder['route_info']['sender_phone'] = $oSender->phone ?? '';
            $builder['route_info']['sender_avatar'] = $oSender->avatar ?? '';
            $builder['route_info']['src'] = $routeInfo['srcDetail'] ?? '';
            $builder['route_info']['receiver_name'] = $oReceiver->name ?? '';
            $builder['route_info']['receiver_phone'] = $oReceiver->phone ?? '';
            $builder['route_info']['receiver_avatar'] = $oReceiver->avatar ?? '';
            $builder['route_info']['dst'] = $routeInfo['dstDetail'] ?? '';
            $builder['cargo_info']['cargo_type'] = $oShipping->cargo_type ?? '';
//            $builder['cargo_info']['cargo_type']       = $oShipping->cargo_type; // 可载货物xxx吨
            $builder['cargo_info']['price'] = $oShipping->price ?? 0; // 15000
            $builder['cargo_info']['price_unit'] = $oShipping->price_unit ?? 0; // 价格单位 1:元/吨,2:元/件,3:元/个,4:元/趟
            $builder['cargo_info']['total_car_num'] = $oShipping->total_car_num ?? 0;
            $builder['cargo_info']['shipping_car_num'] = $oShipping->shipping_car_num ?? 0;
            $builder['cargo_info']['order_remark'] = $oShipping->order_remark ?? '';
            $builder['order_info']['order_no'] = $oShipping->order_no ?? '';
            $builder['order_info']['start_time'] = $oShipping->start_time ?? '';// 接单时间
            $builder['order_info']['load_time'] = $oShipping->load_time ?? '';// 装货时间
            $builder['order_info']['unload_time'] = $oShipping->unload_time ?? '';// 卸货时间
            $builder['order_info']['payment_time'] = $oShipping->payment_status == 10 ? $oShipping->payment_time : ''; // 结算时间
            $builder['order_info']['end_time'] = $oShipping->end_status == 40 ? $oShipping->end_time : ''; // 结单时间
            $builder['order_info']['load_num'] = $oShipping->load_num ?? 0;
            $builder['order_info']['load_pic'] = $oShipping->load_pic ?? '';
            $builder['order_info']['unload_num'] = $oShipping->unload_num ?? 0;
            $builder['order_info']['unload_pic'] = $oShipping->unload_pic ?? '';
            $builder['order_info']['shipping_no'] = $oShipping->shipping_no ?? '';
            $builder['order_info']['pay_status'] = $oShipping->pay_status ?? 0;
            $builder['order_info']['global_status'] = $oShipping->global_status ?? 0;

            // 支付相关信息
            $builder['pay_info']['load_amount'] = $oShipping->pay_load_amount ?? 0; // 应付总金额，单位：元
            $builder['pay_info']['loss_amount'] = $oShipping->pay_loss_amount ?? 0; // 扣损金额，单位：元
            $builder['pay_info']['actual_amount'] = $oShipping->pay_actual_amount ?? 0; // 实付金额，单位：元
            $builder['pay_info']['status'] = $oShipping->pay_status ?? 0; // 支付状态，0待支付，10已支付
            $builder['pay_info']['created_at'] = $oShipping->pay_created_at ?? ''; // 创建时间
            $builder['pay_info']['updated_at'] = $oShipping->pay_updated_at ?? ''; // 更新时间

            return $this->success('数据获取成功', $builder);

        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 司机到达发货地
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function arriveSrc(Request $request)
    {
        try {

            $validator = Validator::make($request->all(), [
                'driver_uuid' => 'required|size:36',
                'shipping_no' => 'required',
            ]);

            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            $driverUuid = $request->get('driver_uuid');
            $shippingNo = $request->get('shipping_no');
            $data['global_status'] = Shipping::GLOBAL_DRIVER_ARRIVE_SRC;

            Shipping::where('driver_uuid', $driverUuid)
                ->where('shipping_no', $shippingNo)
                ->update($data);

            // 发送通知给发货人 - 运单状态为10
            $oShipping = Shipping::query()->where('driver_uuid', $driverUuid)->where('shipping_no', $shippingNo)->firstOrFail();
            $oOrder = Order::query()->where('id', $oShipping->order_id)->firstOrFail();
            $oDriver = Member::query()->where('uuid', $driverUuid)->firstOrFail();
            $oDriverDetail = Driver::query()->where('uuid', $driverUuid)->firstOrFail();
            $routeInfo = RouteService::getInstance()->getDetailedAddressByRouteId($oOrder->route_id, new OwnerRoutes(), [1, 2, 3, 4], [1, 2, 3, 4]);
            $msgContent = sprintf('有新司机到达装货现场，请及时处理。司机名字：%s，电话：%s，车牌：%s，目的地为：%s，到达时间：%s',
                $oDriver->name,
                $oDriver->phone,
                $oDriverDetail->car_no,
                $routeInfo['dstDetail'],
                date('Y年m月d日H:i:s')
            );

            $params = [];
            $oShipper = Member::query()->where('uuid', $oOrder->sender_uuid)->firstOrFail(); // 发货人信息
            if ($oShipper->user_platform == Member::USER_PLATFORM_ANDROID) {
                $params = [
                    'alias_type' => 'user_alias',
                    'alias' => $oOrder->sender_uuid,
                    "ticker" => "有新司机到达装货现场",
                    "title" => "有新司机到达装货现场",
                    "text" => $msgContent,
                    "after_open" => "go_app",
                    "description" => "有新司机到达装货现场",
                ];
            }
            if ($oShipper->user_platform == Member::USER_PLATFORM_IOS) {
                $params = [
                    'alert' => [
                        'title' => '有新司机到达装货现场',
                        'body' => $msgContent,
                    ],
                    'alias_type' => 'user_alias',
                    'alias' => $oOrder->sender_uuid,
                    "description" => '有新司机到达装货现场',
                ];
            }
            NotificationService::fire($oOrder->sender_uuid, $params, new ShippingStatus10Shipper(
                $oDriver->name,
                $oDriver->phone,
                $oDriverDetail->car_no
            ));


            return $this->success('操作成功');

        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 司机已确认装货
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function confirmLoad(Request $request)
    {
        try {

            $validator = Validator::make($request->all(), [
                'driver_uuid' => 'required|size:36',
                'shipping_no' => 'required',
            ]);

            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            $driverUuid = $request->get('driver_uuid');
            $shippingNo = $request->get('shipping_no');
            $data['global_status'] = Shipping::GLOBAL_DRIVER_SHIPMENT;

            Shipping::where('driver_uuid', $driverUuid)
                ->where('shipping_no', $shippingNo)
                ->update($data);

            return $this->success('操作成功');

        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 司机完成装货磅单上传
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function load(Request $request)
    {
        try {

            $validator = Validator::make($request->all(), [
                'driver_uuid' => 'required|size:36',
                'shipping_no' => 'required',
                'load_num' => 'required',
                'load_pic' => 'required',
            ]);

            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            $driverUuid = $request->get('driver_uuid');
            $shippingNo = $request->get('shipping_no');
            $data['status'] = Shipping::$statusLoadComplete;
            $data['load_num'] = $request->get('load_num');
            $data['load_pic'] = $request->get('load_pic');
            $data['shipment_end_time'] = date('Y-m-d H:i:s');
            $data['global_status'] = Shipping::GLOBAL_DRIVER_LOADED;

            Shipping::where('driver_uuid', $driverUuid)
                ->where('shipping_no', $shippingNo)
                ->update($data);

            // 发送通知给发货人 - 运单状态为20
            $oShipping = Shipping::query()->where('driver_uuid', $driverUuid)->where('shipping_no', $shippingNo)->firstOrFail();
            $oOrder = Order::query()->where('id', $oShipping->order_id)->firstOrFail();
            $oDriver = Member::query()->where('uuid', $driverUuid)->firstOrFail();
            $oDriverDetail = Driver::query()->where('uuid', $driverUuid)->firstOrFail();
            $routeInfo = RouteService::getInstance()->getDetailedAddressByRouteId($oOrder->route_id, new OwnerRoutes(), [1, 2, 3, 4], [1, 2, 3, 4]);
            $msgContent = sprintf('有司机上传完发货榜单，请确认。司机名字：%s，电话：%s，车牌：%s，目的地为：%s，订单号为：%s',
                $oDriver->name,
                $oDriver->phone,
                $oDriverDetail->car_no,
                $routeInfo['dstDetail'],
                $oOrder->order_no
            );

            $params = [];
            $oShipper = Member::query()->where('uuid', $oOrder->sender_uuid)->firstOrFail(); // 发货人信息
            if ($oShipper->user_platform == Member::USER_PLATFORM_ANDROID) {
                $params = [
                    'alias_type' => 'user_alias',
                    'alias' => $oOrder->sender_uuid,
                    "ticker" => "有司机上传完发货榜单",
                    "title" => "有司机上传完发货榜单",
                    "text" => $msgContent,
                    "after_open" => "go_app",
                    "description" => "有司机上传完发货榜单",
                ];
            }
            if ($oShipper->user_platform == Member::USER_PLATFORM_IOS) {
                $params = [
                    'alert' => [
                        'title' => '有司机上传完发货榜单',
                        'body' => $msgContent,
                    ],
                    'alias_type' => 'user_alias',
                    'alias' => $oOrder->sender_uuid,
                    "description" => '有司机上传完发货榜单',
                ];
            }
            NotificationService::fire($oOrder->sender_uuid, $params, new ShippingStatus20Shipper(
                $oDriver->name,
                $oDriver->phone,
                $oDriverDetail->car_no
            ));

            return $this->success('操作成功');

        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }


    /**
     * 司机已确认卸货
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function confirmUnload(Request $request)
    {
        try {

            $validator = Validator::make($request->all(), [
                'driver_uuid' => 'required|size:36',
                'shipping_no' => 'required',
            ]);

            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            $driverUuid = $request->get('driver_uuid');
            $shippingNo = $request->get('shipping_no');

            // 发货人确认装货后，司机才可确认卸货
            $oShipping = Shipping::where('driver_uuid', $driverUuid)->where('shipping_no', $shippingNo)->firstOrFail();
            if ($oShipping->global_status < Shipping::GLOBAL_SENDER_LOAD_CONFIRM) {
                throw new \Exception('发货人确认装货后才可确认卸货');
            }

            $oShipping->global_status = Shipping::GLOBAL_DRIVER_ARRIVE_DST;
            $oShipping->save();

            // 发送通知给收货人 - 运单状态为30
            $oOrder = Order::query()->where('id', $oShipping->order_id)->firstOrFail();
            $oDriver = Member::query()->where('uuid', $driverUuid)->firstOrFail();
            $oDriverDetail = Driver::query()->where('uuid', $driverUuid)->firstOrFail();
            $msgContent = sprintf('有新司机到达交货现场，等待收货，请及时处理。司机名字：%s，电话：%s，车牌：%s，到达时间：%s',
                $oDriver->name,
                $oDriver->phone,
                $oDriverDetail->car_no,
                date('Y年m月d日H:i:s')
            );

            $params = [];
            $oReceiver = Member::query()->where('uuid', $oOrder->receiver_uuid)->firstOrFail(); // 发货人信息
            if ($oReceiver->user_platform == Member::USER_PLATFORM_ANDROID) {
                $params = [
                    'alias_type' => 'user_alias',
                    'alias' => $oOrder->receiver_uuid,
                    "ticker" => "有新司机到达交货现场",
                    "title" => "有新司机到达交货现场",
                    "text" => $msgContent,
                    "after_open" => "go_app",
                    "description" => "有新司机到达交货现场",
                ];
            }
            if ($oReceiver->user_platform == Member::USER_PLATFORM_IOS) {
                $params = [
                    'alert' => [
                        'title' => '有新司机到达交货现场',
                        'body' => $msgContent,
                    ],
                    'alias_type' => 'user_alias',
                    'alias' => $oOrder->receiver_uuid,
                    "description" => '有新司机到达交货现场',
                ];
            }
            NotificationService::fire($oOrder->receiver_uuid, $params, new ShippingStatus30Receiver(
                $oDriver->name,
                $oDriver->phone,
                $oDriverDetail->car_no
            ));


            return $this->success('操作成功');

        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 卸货完成
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function unload(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'driver_uuid' => 'required|size:36',
                'shipping_no' => 'required',
                'unload_num' => 'required',
                'unload_pic' => 'required',
            ]);

            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            $driverUuid = $request->get('driver_uuid');
            $shippingNo = $request->get('shipping_no');
            //$data['status']           = Shipping::$statusUnLoadComplete; //状态还处于运输中，需要收货人确定收货后才更新
            $data['unload_num'] = $request->get('unload_num');
            $data['unload_pic'] = $request->get('unload_pic');
            $data['deliver_end_time'] = date('Y-m-d H:i:s');
            $data['global_status'] = Shipping::GLOBAL_DRIVER_UNLOADED;

            Shipping::where('driver_uuid', $driverUuid)
                ->where('shipping_no', $shippingNo)
                ->update($data);


            // 发送通知给收货人，运单状态为35
            $oShipping = Shipping::query()->where('driver_uuid', $driverUuid)->where('shipping_no', $shippingNo)->firstOrFail();
            $oOrder = Order::query()->where('id', $oShipping->order_id)->firstOrFail();
            $oDriver = Member::query()->where('uuid', $driverUuid)->firstOrFail();
            $msgContent = sprintf('有司机上传完发货榜单，请确认。司机名字：%s，电话：%s',
                $oDriver->name,
                $oDriver->phone
            );

            $params = [];
            $oReceiver = Member::query()->where('uuid', $oOrder->receiver_uuid)->firstOrFail(); // 发货人信息
            if ($oReceiver->user_platform == Member::USER_PLATFORM_ANDROID) {
                $params = [
                    'alias_type' => 'user_alias',
                    'alias' => $oOrder->receiver_uuid,
                    "ticker" => "有司机上传完发货榜单，请确认",
                    "title" => "有司机上传完发货榜单，请确认",
                    "text" => $msgContent,
                    "after_open" => "go_app",
                    "description" => "有司机上传完发货榜单，请确认",
                ];
            }
            if ($oReceiver->user_platform == Member::USER_PLATFORM_IOS) {
                $params = [
                    'alert' => [
                        'title' => '有司机上传完发货榜单，请确认',
                        'body' => $msgContent,
                    ],
                    'alias_type' => 'user_alias',
                    'alias' => $oOrder->receiver_uuid,
                    "description" => '有司机上传完发货榜单，请确认',
                ];
            }
            NotificationService::fire($oOrder->receiver_uuid, $params, new ShippingStatus35Receiver(
                $oDriver->name,
                $oDriver->phone
            ));


            return $this->success('操作成功');

        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 司机确定需要支付的金额
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function confirmAmount(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'driver_uuid' => 'required|size:36',
                'shipping_no' => 'required',
                'bank_id' => 'required|integer',
            ]);
            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            $driverUuid = $request->get('driver_uuid');
            $shippingNo = $request->get('shipping_no');

            $bank = DriverBank::where('id', $request->get('bank_id'))
                ->where('driver_uuid', $driverUuid)
                ->first();
            if (is_null($bank)) {
                throw new \Exception('没有找到bank的记录');
            }

            $shipping = Shipping::where('driver_uuid', $driverUuid)
                ->where('shipping_no', $shippingNo)
                ->first();
            if (is_null($shipping)) {
                throw new \Exception('没有找到shipping的记录');
            }

            // 金额确认 修改状态
            $shipping->global_status = Shipping::GLOBAL_DRIVER_CONFIRM_AMOUNT;
            $shipping->save();

            //银行卡确认
            ShippingPay::where('shipping_id', $shipping->id)
                ->update([
                    'bank_id' => $bank->id
                ]);


            //++++++@start - 发送通知给所有财务 - 运单状态为45
            $oOrder = Order::query()->where('id', $shipping->order_id)->firstOrFail();
            $oDriver = Member::query()->where('uuid', $driverUuid)->firstOrFail();
            $oDriverDetail = Driver::query()->where('uuid', $driverUuid)->firstOrFail();
            $routeInfo = RouteService::getInstance()->getDetailedAddressByRouteId($oOrder->route_id, new OwnerRoutes(), [1, 2, 3, 4], [1, 2, 3, 4]);
//            $msgContent    = sprintf('有司机上传完发货榜单，请确认。司机名字：%s，电话：%s，车牌：%s，目的地为：%s，订单号为：%s',
            $msgContent = sprintf('有司机完成送货任务，需要支付费用，请处理。司机名字：%s，电话：%s，车牌：%s，目的地为：%s，运单号为：%s',
                $oDriver->name,
                $oDriver->phone,
                $oDriverDetail->car_no,
                $routeInfo['dstDetail'],
                $shippingNo
            );

            // 根据货主找到所有财务
            $oOrder = Order::query()->where('id', $shipping->order_id)->firstOrFail();
            $ownerUuid = $oOrder->owner_uuid;
            $oOwner = Member::query()->where('uuid', $ownerUuid)->firstOrFail();

            $financeIds = MemberRelation::query()
                ->where('parent_id', $oOwner->id)
                ->whereRaw('find_in_set(?, role_id)', [23])
                ->pluck('member_id')
                ->toArray();
            $finances = Member::query()->whereIn('id', $financeIds)->get()->toArray();

            foreach ($finances as $finance) {
                if ($finance['user_platform'] == Member::USER_PLATFORM_ANDROID) {
                    $params = [
                        'alias_type' => 'user_alias',
                        'alias' => $finance['uuid'],
                        "ticker" => "有司机完成送货任务，需要支付费用，请处理。",
                        "title" => "有司机完成送货任务，需要支付费用，请处理。",
                        "text" => $msgContent,
                        "after_open" => "go_app",
                        "description" => "有司机完成送货任务，需要支付费用，请处理。",
                    ];
                }
                if ($finance['user_platform'] == Member::USER_PLATFORM_IOS) {
                    $params = [
                        'alert' => [
                            'title' => '有司机完成送货任务，需要支付费用，请处理。',
                            'body' => $msgContent,
                        ],
                        'alias_type' => 'user_alias',
                        'alias' => $finance['uuid'],
                        "description" => '有司机完成送货任务，需要支付费用，请处理。',
                    ];
                }
                NotificationService::fire($oOrder->sender_uuid, $params, new ShippingStatus45Finance(
                    $shippingNo,
                    $oDriver->name,
                    $oDriver->phone,
                    $oDriverDetail->car_no,
                    $routeInfo['dstDetail']
                ));
            }
            //++++++@end - 发送通知给所有财务 - 运单状态为45


            return $this->success('操作成功');

        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 司机确认支付
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function pay(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'driver_uuid' => 'required|size:36',
                'shipping_no' => 'required',
            ]);

            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }

            $driverUuid = $request->get('driver_uuid');
            $shippingNo = $request->get('shipping_no');
            $data['status'] = Shipping::$statusTransportPayComplete;
            $data['pay_status'] = Shipping::PAY_CONFIRM;
            $data['global_status'] = Shipping::GLOBAL_DRIVER_CONFIRM_PAYED;

            Shipping::where('driver_uuid', $driverUuid)
                ->where('shipping_no', $shippingNo)
                ->update($data);

            return $this->success('操作成功');

        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }


    /***
     * @param $driverUuid  司机用户id
     * @param remark_cancel 取消订单得原因
     * @param remark_cancel 取消订单得原因
     * @author sql
     * 司机违约 取消运单
     * 思路：1.根据请求得司机用户id(driver_uuid)查看此司机是否存在
     *      2.验证是否存在当前运单
     *      3.验证当前运单的状态，只要是未完成的，都可以取消
     *     4.设置违约状态，并填写违约原因
     */
    public function cancelShippingByDrivers(Request $request)
    {
        try {
            $driverUuid = $request->get('driver_uuid');
            $shipping_no = $request->get('shipping_no');
            $remark_cancel = $request->get('remark_cancel');
            $validator = Validator::make($request->all(), [
                'driver_uuid' => 'required|size:36',
                'remark_cancel' => 'required',
                'shipping_no' => 'required',
            ], [
                'required' => ':attribute为必填项',
                'min' => ':attribute长度不符合要求',
            ], [
                'driver_uuid' => '当前司机用户id',
                'remark_cancel' => '违约原因',
                'shipping_no' => '运单号',
            ]);

            if ($validator->fails()) {
                throw new \Exception($validator->errors()->first());
            }


            //验证当前传输得司机Uuid，是否存在此用户
            $oDriver = Member::with(['driver', 'audit'])->where('uuid', $driverUuid)->firstOrFail();
            if (!$oDriver) {
                $this->error('当前用户信息未获取到');
            }
            //验证是否存在当前运单
            $oShipping = Shipping:: where('shipping_no', $shipping_no)->where('driver_uuid', $driverUuid)->first();
            if (is_null($oShipping)) {
                throw new \Exception('该运单不存在');
            }

            if ($oShipping->status == '-2') {
                throw new \Exception('当前运单已提交违约申请');
            }
            if ($oShipping->pay_status == 10 || $oShipping->status == 40 || $oShipping->global_status == 50) {
                throw new \Exception('当前运单货主已付款无法违约');
            }
            //更改状态，存入违约原因
            $oShipping->remark_cancel = $remark_cancel;
            $oShipping->cancel_status = 0;//待审核
            $oShipping->status = -2;//-2申请违约取消运单
            $oShipping->global_status = -2;//-2申请违约取消运单
            if ($oShipping->save()) {
                return $this->success('提交成功', '');
            }

            throw new \Exception('提交失败', '');

        } catch (ModelNotFoundException $e) {
            return $this->error(Common::notFoundModelFormat($e->getModel()));
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }

    }
}